package com.tongfusoft.web.core.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.tongfusoft.da.DataAccessSession;
import com.tongfusoft.da.DataAccessSessionFactory;
import com.tongfusoft.da.help.DBUtils;
import com.tongfusoft.exception.ServiceException;
import com.tongfusoft.web.core.annotation.UniqueCheck;
import com.tongfusoft.web.core.data.BaseData;
import com.tongfusoft.web.core.service.IManagementService;

public class ManagementServiceAdapter implements IManagementService<BaseData> {
	protected Log log = LogFactory.getLog(ManagementServiceAdapter.class);
	
	@Override
	public boolean add(BaseData obj){
		if(checkUnique(obj)){
			if(DBUtils.executeInsert(obj.getAddTag(), obj.getInsertMap()) == 1){
				return true;
			}else{
				return false;
			}
		}else{
			throw new ServiceException("有重复数据","common.prompt.uniqueerror");
		}
	}
	
	@Override
	public boolean update(BaseData obj){
		if(DBUtils.executeUpdate(obj.getUpdateTag(), obj.getUpdateMap()) == 1){
			return true;
		}else{
			return false;
		}
	}
	
	@Override
	public boolean remove(BaseData obj){
		if(DBUtils.executeDelete(obj.getRemoveTag(), obj.getRemoveMap()) == 1){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 唯一性检测
	 * @return
	 */
	protected boolean checkUnique(BaseData obj){
		//默认根据设定的唯一性字段进行检验
		List<String> checkSql = new ArrayList<String>();
		if(obj.getClass().isAnnotationPresent(UniqueCheck.class)){
			UniqueCheck annotation = obj.getClass().getAnnotation(UniqueCheck.class);
			//转换成json
			JSONArray uniques = JSONArray.fromObject(annotation.value());
			
			for(int i=0;i<uniques.size();i++){
				JSONObject unique = uniques.getJSONObject(i);
				StringBuffer sql = new StringBuffer();
				sql.append("select count(*) as TOTALNUM from ").append(obj.getTableName()).append(" where 1=1 ");
				Iterator<String> iter = unique.keys();
				while(iter.hasNext()){
					String key = iter.next();
					sql.append(" and ").append(key).append(" = #{").append(unique.getString(key)).append("} ");
				}

				checkSql.add(sql.toString());
			}
			
		}
		
		for(String sql : checkSql){
			Map<String,Object> params = obj.getInsertMap();
			List<Map<String, Object>> result = DBUtils.executeSelectDynamic(sql, params);
			if(((Number) result.get(0).get("TOTALNUM")).intValue() > 0){
				return false;
			}
		}
		
		return true;
	}
	
	@Override
	public boolean add(List<BaseData> list){
		if(list != null && list.size() > 0){
			DataAccessSession session = null;
			try{
				session = DataAccessSessionFactory.openSession(false);
				for(BaseData data : list){
					DBUtils.executeInsert(data.getAddTag(),data.getInsertMap(),session);
				}
				session.commit();
				return true;
			} catch (Exception e){
				log.error(e);
				session.rollback();
				throw new ServiceException(e);
			} finally {
				session.close();
			}
			
		}
		return true;
	}
	
	@Override
	public boolean remove(List<BaseData> list){
		if(list != null && list.size() > 0){
			DataAccessSession session = null;
			try{
				session = DataAccessSessionFactory.openSession(false);
				for(BaseData data : list){
					DBUtils.executeDelete(data.getRemoveTag(), data.getRemoveMap(), session);
				}
				session.commit();
				return true;
			} catch (Exception e){
				log.error(e);
				session.rollback();
				throw new ServiceException(e);
			} finally {
				session.close();
			}
			
		}
		return true;
	}
	
	@Override
	public boolean update(List<BaseData> list){
		if(list != null && list.size() > 0){
			DataAccessSession session = null;
			try{
				session = DataAccessSessionFactory.openSession(false);
				for(BaseData data : list){
					DBUtils.executeDelete(data.getUpdateTag(), data.getUpdateMap(), session);
				}
				session.commit();
				return true;
			} catch (Exception e){
				log.error(e);
				session.rollback();
				throw new ServiceException(e);
			} finally {
				session.close();
			}
			
		}
		return true;
	}
	
}
